﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Streambolics.Hp41s
{
    /// <summary>
    ///     An execution context where the user is in control.
    /// </summary>

    public class InteractiveContext : Context
    {
        private InstructionFactory _Factory; 

        internal InteractiveContext (Engine aMachine)
            : base (aMachine)
        {
        }

        public InteractiveContext (Context aParent)
            : base (aParent)
        {
        }

        protected internal override void Execute (Instruction aInstruction)
        {
            Machine.Cld ();
            aInstruction.ExecuteInteractive (this);
        }

        protected internal override bool Run ()
        {
            Machine.DoDisplayChanged ();
            return base.Run ();
        }

        public override void KeyClick (int aKey)
        {
            if (_Factory != null)
            {
                SetFactory (_Factory.InterpretKey (aKey));
            }

            SetFactory (Keyboard().Assigned(aKey, Parent));
        }

        public KeyboardMapping Keyboard ()
        {
            return Machine.Keyboard ();
        }

        private void SetFactory (InstructionFactory aFactory)
        {
            if (aFactory == null)
            {
                throw new NonexistentException ();
            }

            if (aFactory != null)
            {
                if (aFactory.InstructionAvailable)
                {
                    Execute (aFactory.ToInstruction());
                    aFactory = null;
                }
            }

            _Factory = aFactory;
        }

        public override void DoCondition (bool aCondition)
        {
            DoPrompt (aCondition ? "YES" : "NO");
        }

        public override void DoGto (Steps aProgram, int aProgramCounter)
        {
            if (Parent is RunningContext)
            {
                Parent.DoGto (aProgram, aProgramCounter);
            }
            else
            {
                throw new Exception ("GTO Not implemented in interactivecontext");
            }
        }
    }
}
